GAN Generator & Discriminator

바닐라(vanilla) GAN
위의 모델은 원본 GAN 모델이다.
Generator와 Discriminator의 은닉층에는 LeakyReLU 활성화 함수를 사용한다.
(ReLU를 사용하면, 희소한 그레이디언트가 발생하기 때문에, 입력 값 전 범위에 걸쳐 그레이디언트가 필요한 경우 적합하지 않다.)
판별자 신경망은 각 은닉층 다음에는 드롭아웃층이 뒤따른다.
생성자의 출력층은 하이퍼볼릭 탄젠트(tanh) 활성화 함수를 사용한다.

판별자의 출력층은 로짓을 계산하기 위해서 활성화 함수를 가지지 않던지(선형 활성화 함수 y=x)
확률을 출력으로 얻기 위해 시그모이드 활성화 함수를 사용할 수 있다.
LeakyReLU
ReLU 활성화 함수는 음수 입력은 버린다.(음수 영역은 0으로 설정)
이로 인해 ReLU 활성화 함수는 역전파될 때, 희소한 그레이디언트를 만들 수 있다.

희소한 그레이디언트가 분류 모델에는 도움이 될 수 있지만, GAN 같은 일부 애플리케이션에서는 입력 값의
전 범위에 대한 그레이디언트를 사용하는 것이 좋다.
음수 값을 일정 수준 출력하도록 하기 위해서 ReLU 함수를 수정한 위와 같은 활성화 함수를 Leaky ReLU라고 부른다.

Leaky ReLU 활성화 함수는 음수 영역에서도 0이 아닌 그레이디언트를 만든다.
helper functions
import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np
import matplotlib.pyplot as plt
def make_generator_network(num_hidden_layers=1, num_hidden_units=100, num_output_units=784):
model=tf.keras.Sequential()
for i in range(num_hidden_layers):
model.add(tf.keras.layers.Dense(units=num_hidden_units, use_bias=False))
model.add(tf.keras.layers.LeakyReLU())
model.add(tf.keras.layers.Dense(units=num_output_units, activation='tanh'))
return model
def make_discriminator_network(num_hidden_layers=1, num_hidden_units=100, num_output_units=1):
model=tf.keras.Sequential()
for i in range(num_hidden_layers):
model.add(tf.keras.layers.Dense(units=num_hidden_units))
model.add(tf.keras.layers.LeakyReLU())
model.add(tf.keras.layers.Dropout(rate=0.5))
model.add(tf.keras.layers.Dense(units=num_output_units, activation=None))
return model
MNIST 28x28 흑백 사진을 판별자의 입력, 생성자의 출력으로 사용
model build
image_size=(28, 28)
z_size=20
mode_z='uniform' #uniform or normal
gen_hidden_layers=1
gen_hidden_size=100
disc_hidden_layers=1
disc_hidden_size=100
tf.random.set_seed(1)
gen_model=make_generator_network(
num_hidden_layers=gen_hidden_layers,
num_hidden_units=gen_hidden_size,
num_output_units=np.prod(image_size))
gen_model.build(input_shape=(None, z_size))
disc_model=make_discriminator_network(
num_hidden_layers=disc_hidden_layers,
num_hidden_units=disc_hidden_size)
disc_model.build(input_shape=(None, np.prod(image_size)))
gen_model.summary()
disc_model.summary()

Model: "sequential"

_________________________________________________________________

Layer (type)                 Output Shape              Param #   

=================================================================

dense (Dense)                (None, 100)               2000      

_________________________________________________________________

leaky_re_lu (LeakyReLU)      (None, 100)               0         

_________________________________________________________________

dense_1 (Dense)              (None, 784)               79184     

=================================================================

Total params: 81,184

Trainable params: 81,184

Non-trainable params: 0

_________________________________________________________________



Model: "sequential_1"

_________________________________________________________________

Layer (type)                 Output Shape              Param #   

=================================================================

dense_2 (Dense)              (None, 100)               78500     

_________________________________________________________________

leaky_re_lu_1 (LeakyReLU)    (None, 100)               0         

_________________________________________________________________

dropout (Dropout)            (None, 100)               0         

_________________________________________________________________

dense_3 (Dense)              (None, 1)                 101       

=================================================================

Total params: 78,601

Trainable params: 78,601

Non-trainable params: 0

_________________________________________________________________